home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / AquaShade / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  8.4 KB  |  269 lines

  1. /*
  2.  
  3. AquaShade hack
  4. MacHack 2001
  5.  
  6. Nicholas Riley
  7. Avi Drissman
  8.  
  9. with thanks to:
  10. Mike Ferris
  11. Chris Nebel
  12. Ed Wynne
  13. Shawn Platkus
  14.  
  15. Known funkiness:
  16. Sometimes, a collapsed window will not get the proper deactivated appearance. No idea why.
  17. Often, the window widget glyphs will stay around after the mouse leaves their proximity.
  18. Probably due to the fact that we do window attribute slamming.
  19.  
  20. */
  21.  
  22. #include "main.h"
  23.  
  24. DEFINE_ONE_SHOT_HANDLER_GETTER(MinEventHandler)
  25. DEFINE_ONE_SHOT_HANDLER_GETTER(TicTacEventHandler)
  26. DEFINE_ONE_SHOT_HANDLER_GETTER(CloseEventHandler)
  27.  
  28. void InitAquaShade(void)
  29. {
  30.     static EventLoopTimerUPP eventLoopTimer;
  31.     if (!eventLoopTimer)
  32.         eventLoopTimer = NewEventLoopTimerUPP(EventTimer);
  33.     
  34.     InstallEventLoopTimer(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, eventLoopTimer, nil, nil);
  35.     PatchEveryWindow();
  36. }
  37.  
  38. void PatchEveryWindow(void) // Ford every stream...
  39. {
  40.     WindowRef window;
  41.     
  42.     window = GetWindowList();
  43.     while (window)
  44.     {
  45.         PatchWindow(window);
  46.         window = MacGetNextWindow(window);
  47.     }
  48. }
  49.  
  50. void PatchWindow(WindowRef window)
  51. {
  52.     EventTypeSpec minList[] = {{kEventClassWindow, kEventWindowCollapse},
  53.                                 {kEventClassWindow, kEventWindowCollapseAll}};
  54.     EventTypeSpec ttList = {kEventClassWindow, kEventWindowToolbarSwitchMode};
  55.     EventTypeSpec closeList[] = {{kEventClassWindow, kEventWindowClose},
  56.                                   {kEventClassWindow, kEventWindowCloseAll}};
  57.  
  58.     InstallWindowEventHandler(window, GetMinEventHandlerUPP(), 2, minList, nil, nil);
  59.     InstallWindowEventHandler(window, GetTicTacEventHandlerUPP(), 1, &ttList, nil, nil);
  60.     InstallWindowEventHandler(window, GetCloseEventHandlerUPP(), 2, closeList, nil, nil);
  61. }
  62.  
  63. // XXX this is broken
  64. OSStatus pascal CloseEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) {
  65.     WindowRef window;
  66.  
  67.     fprintf(stderr, "I'm closing...\n");
  68.     switch (GetEventKind (inEvent))
  69.     {
  70.         case kEventWindowClose:
  71.             // Get the window
  72.             if (GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window))
  73.                 return CallNextEventHandler(inHandlerCallRef, inEvent); //?
  74.             WindowShade(window, false);
  75.             break;
  76.         case kEventWindowCloseAll:
  77.             window = GetWindowList();
  78.             while (window)
  79.             {
  80.                 WindowShade(window, false);
  81.                 window = MacGetNextWindow(window);
  82.             }
  83.     }
  84.     return CallNextEventHandler(inHandlerCallRef, inEvent);
  85. }
  86.  
  87. OSStatus pascal MinEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
  88. {
  89.     WindowRef window;
  90.     
  91.     if (GetCurrentKeyModifiers() & (controlKey | rightControlKeyBit))
  92.         return CallNextEventHandler(inHandlerCallRef, inEvent);
  93.  
  94.     // Get the window
  95.     if (GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window))
  96.         return CallNextEventHandler(inHandlerCallRef, inEvent); //?
  97.     
  98.     switch (GetEventKind(inEvent))
  99.     {
  100.         case kEventWindowCollapse:
  101.             WindowShade(window, !(GetCurrentKeyModifiers() & (shiftKey | rightShiftKeyBit)));
  102.             break;
  103.         
  104.         case kEventWindowCollapseAll:
  105.             window = GetWindowList();
  106.             while (window)
  107.             {
  108.                 WindowShade(window, !(GetCurrentKeyModifiers() & (shiftKey | rightShiftKeyBit)));
  109.                 window = MacGetNextWindow(window);
  110.             }
  111.             break;
  112.     }
  113.     
  114.     
  115.     return noErr;
  116. }
  117.  
  118. OSStatus pascal TicTacEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
  119. {
  120.     WindowRef window;
  121.     Boolean collapsed = false;
  122.  
  123.     // Get the window
  124.     GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window);
  125.     
  126.     // Is it collapsed?
  127.     GetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), nil, &collapsed); // if property isn't there, then we've never touched the window, and it's expanded...
  128.     
  129.     if (collapsed)
  130.         return noErr; // ignore
  131.     else
  132.         return CallNextEventHandler(inHandlerCallRef, inEvent);
  133. }
  134.  
  135. void pascal EventTimer(EventLoopTimerRef inTimer, void *inUserData)
  136. {
  137.     PatchEveryWindow();
  138. }
  139.  
  140. void WindowShade(WindowRef window, Boolean slide)
  141. {
  142.     Boolean collapsed = false;
  143.     struct WindowInfo winfo;
  144.  
  145.     // Should we be expanding or contracting?
  146.     if (GetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), nil, &collapsed))
  147.         collapsed = false;
  148.     
  149.     PlaySound();
  150.     
  151.     if (collapsed)
  152.     {
  153.         Rect newRect;
  154.         if (slide)
  155.         {
  156.             GetWindowBounds(window, kWindowGlobalPortRgn, &newRect);
  157.             if (newRect.top != 0) newRect.top -= kWindowTitleBarHeight;
  158.         }
  159.         
  160.         // we need to restore it
  161.         GetWindowProperty(window, 'AShd', 'Winf', sizeof(winfo), nil, &winfo);
  162.         
  163.         if (slide)
  164.         {
  165.             Point offset;
  166.             offset.h = newRect.left - winfo.oldSize.left;
  167.             offset.v = newRect.top - winfo.oldSize.top;
  168.             winfo.oldSize.top += offset.v;
  169.             winfo.oldSize.bottom += offset.v;
  170.             winfo.oldSize.left += offset.h;
  171.             winfo.oldSize.right += offset.h;
  172.             TransitionWindow(window, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &winfo.oldSize);
  173.         }
  174.         else
  175.         {
  176.             SizeWindow(window, winfo.oldSize.right - winfo.oldSize.left, winfo.oldSize.bottom - winfo.oldSize.top - ((newRect.top != 0) ? kWindowTitleBarHeight : 0), true);
  177.         }
  178.         ChangeWindowAttributes(window, kWindowNoAttributes, 0xFFFFFFFF);
  179.         ChangeWindowAttributes(window, winfo.oldAttrs, kWindowNoAttributes);
  180.         
  181.         collapsed = false;
  182.         SetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), &collapsed);
  183.         
  184.     }
  185.     else // must collapse it
  186.     {
  187.         if (slide)
  188.         {
  189.             GetWindowBounds(window, kWindowGlobalPortRgn, &winfo.oldSize);
  190.             if (winfo.oldSize.top != 0) winfo.oldSize.top -= kWindowTitleBarHeight;
  191.         }
  192.         else
  193.         {
  194.             GetWindowBounds(window, kWindowContentRgn, &winfo.oldSize);
  195.             if (winfo.oldSize.top != 0) winfo.oldSize.bottom += kWindowTitleBarHeight;
  196.         }
  197.         GetWindowAttributes(window, &winfo.oldAttrs);
  198.         SetWindowProperty(window, 'AShd', 'Winf', sizeof(winfo), &winfo);
  199.         
  200.         // take away inconvenient "features"
  201.         ChangeWindowAttributes(window, kWindowNoShadowAttribute, kWindowFullZoomAttribute | kWindowResizableAttribute);
  202.         
  203.         if (GetCurrentKeyModifiers() & alphaLock) {
  204.             GrafPtr oldPort;
  205.             Rect rect = {0x8000, 0x8000, 0x7fff, 0x7fff};
  206.             Pattern blackPat;
  207.             
  208.             GetPort(&oldPort);
  209.             SetPortWindowPort(window);
  210.             ForeColor(blackColor);
  211.             FillRect(&rect, GetQDGlobalsBlack(&blackPat));
  212.             SetPort(oldPort);
  213.         }
  214.  
  215.         // collapse
  216.         if (slide)
  217.         {
  218.             winfo.oldSize.bottom = winfo.oldSize.top + 1;
  219.             if (winfo.oldSize.top != 0) winfo.oldSize.bottom += kWindowTitleBarHeight;
  220.             TransitionWindow(window, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &winfo.oldSize);
  221.         }
  222.         else
  223.         {
  224.             SizeWindow(window, winfo.oldSize.right - winfo.oldSize.left, 1, true);
  225.         }
  226.         
  227.         collapsed = true;
  228.         SetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), &collapsed);
  229.     }
  230. }
  231.  
  232. void PlaySound() {
  233.     SysBeep(100);
  234.     /*
  235.     FSRef fref;
  236.     OSErr err = FSPathMakeRef("/Users/avidriss/AquaShade/open", &fref, NULL);
  237.     Movie movie;
  238.     FSSpec fsp;
  239.     short refnum;
  240.     
  241.     if (err != noErr) ExitToShell();
  242.  
  243.     err = FSGetCatalogInfo(&fref, 0, NULL, NULL, &fsp, NULL);
  244.     if (err != noErr) ExitToShell();
  245.     /*
  246.     OpenMovieFile(&fsp, &refnum, fsRdPerm);
  247.     NewMovieFromFile(&movie, refnum, NULL, (StringPtr)NULL, newMovieActive, NULL);
  248.     if (refnum != 0)
  249.         CloseMovieFile(refnum);
  250.             
  251.     // play the movie once thru
  252.     StartMovie(movie);
  253.     while (!IsMovieDone(movie))
  254.         MoviesTask(movie, 0);
  255.     DisposeMovie(movie);
  256.     
  257.     
  258.     err = FSpOpenDF( &fsp, fsRdPerm, 
  259.                                   &refnum );
  260.     if ( err != noErr )
  261.       ExitToShell();
  262.  
  263.     err = SndStartFilePlay( nil, refnum, 0, 40960, nil, nil, nil, false );
  264.     if ( err != noErr )
  265.       ExitToShell();
  266.     */
  267.  }
  268.  
  269.